﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using PasteTimer.noticemodels;
using PasteTimer.taskmodels;
using PasteTimer.usermodels;
using Volo.Abp.DependencyInjection;

namespace PasteTimer.HttpApi.Host.Service
{
    /// <summary>
    /// 系统初始化
    /// </summary>
    public class SystemStartHandler : ISingletonDependency
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly TaskConfig _config;
        //private readonly TaskNodeConfig _nodeConfig;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="config"></param>
        public SystemStartHandler(
            IServiceProvider serviceProvider,
            IOptions<TaskConfig> config)
        {
            _serviceProvider = serviceProvider;
            _config = config.Value;
            //_nodeConfig = nodeConfig.Value;
        }

        #region 初始化系统相关


        /// <summary>
        /// 
        /// </summary>
        public async Task<bool> SystemStart()
        {

            using var _scope = _serviceProvider.CreateScope();
            using var _dbContext = _scope.ServiceProvider.GetRequiredService<IPasteTimerDbContext>();
            //初始化密钥校验
            if (_dbContext.Database.GetPendingMigrations().Any())
            {
                var migrations = _dbContext.Database.GetPendingMigrations().ToList();
                _dbContext.Database.Migrate();
                foreach (var item in migrations)
                {
                    if (item.EndsWith("task_bind"))
                    {
                        var list = new List<TaskBindUser>();
                        var _userids = _dbContext.UserInfo.Where(x => x.IsEnable).Select(x => x.Id).ToArray();
                        if (_userids != null && _userids.Length > 0)
                        {
                            var taskids = _dbContext.TaskInfo.Where(x => true).Select(x => x.Id).ToArray();
                            if (taskids != null && taskids.Length > 0)
                            {
                                foreach (var taskid in taskids)
                                {
                                    foreach (var userid in _userids)
                                    {
                                        list.Add(new TaskBindUser
                                        {
                                            CreateDate = DateTime.Now,
                                            Create_UserId = 0,
                                            TaskId = taskid,
                                            UserId = userid
                                        });
                                    }
                                }
                            }
                        }
                        if (list.Count > 0)
                        {
                            _dbContext.AddRange(list);
                            await _dbContext.SaveChangesAsync();
                        }
                        continue;
                    }
                }
            }

            //创建基础权限
            var rootid = await _AddRole(_dbContext, "root", "root", "最高管理权限");
            await _AddRole(_dbContext, "data", "add", "添加数据的权限");
            await _AddRole(_dbContext, "data", "update", "修改数据的权限");
            await _AddRole(_dbContext, "data", "state", "更改数据的状态权限");
            await _AddRole(_dbContext, "data", "bind", "绑定权限");
            await _AddRole(_dbContext, "data", "del", "删除数据的状态权限");
            await _AddRole(_dbContext, "user", "auth", "更改角色组绑定权限");
            await _AddRole(_dbContext, "user", "update", "更改账号权限");
            //创建基础角色
            var adminid = 0;
            var admin = await _dbContext.UserInfo.Where(x => x.Email == _config.Email).AsNoTracking().FirstOrDefaultAsync();
            if (admin == null || admin == default)
            {
                var _user = new UserInfo();
                _user.Email = _config.Email;
                _user.UserName = "管理员";
                _user.CreateDate = DateTime.Now;
                _user.Grade = "admin";
                _user.IsEnable = true;
                _user.PassWord = _config.Password.ToMd5Lower();
                _dbContext.Add(_user);
                await _dbContext.SaveChangesAsync();
                adminid = _user.Id;

                //创建组
                var groupid = 0;
                var group = await _dbContext.GradeInfo.Where(x => x.Name == "admin").AsNoTracking().FirstOrDefaultAsync();
                if (group == null || group == default)
                {
                    var item = new GradeInfo();
                    item.Name = "admin";
                    item.Desc = "管理组";
                    item.IsEnable = true;
                    _dbContext.Add(item);
                    await _dbContext.SaveChangesAsync();
                    groupid = item.Id;
                }
                else
                {
                    groupid = group.Id;
                }
                //绑定角色组

                var bind = await _dbContext.GradeRole.Where(x => x.GradeId == groupid && x.RoleId == rootid).AsNoTracking().FirstOrDefaultAsync();
                if (bind == null || bind == default)
                {
                    var item = new GradeRole();
                    item.GradeId = groupid;
                    item.RoleId = rootid;
                    _dbContext.Add(item);
                    await _dbContext.SaveChangesAsync();
                }


                await _addnoticemessage(_dbContext, "sendexception", "发送任务给节点失败！", 300);
                await _addnoticemessage(_dbContext, "healthexception", "节点健康检查失败！", 300);
                await _addnoticemessage(_dbContext, "nodenotfound", "没有找到可以工作的节点！", 300);
                await _addnoticemessage(_dbContext, "workfail", "执行任务失败！", 300);

                await AddSystemHandler(_dbContext);

            }
            else
            {
                adminid = admin.Id;
            }

            _dbContext.Dispose();
            _scope.Dispose();


            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="model"></param>
        /// <param name="role"></param>
        /// <param name="desc"></param>
        /// <returns></returns>
        private async Task<int> _AddRole(IPasteTimerDbContext _dbContext, string model, string role, string desc)
        {
            var find = await _dbContext.RoleInfo.Where(x => x.Model == model && x.Name == role).AsNoTracking().FirstOrDefaultAsync();
            if (find != null && find != default)
            {
                return find.Id;
            }
            else
            {
                var item = new RoleInfo();
                item.Name = role;
                item.Model = model;
                item.Sort = 100;
                item.IsEnable = true;
                item.Desc = desc;
                _dbContext.Add(item);
                await _dbContext.SaveChangesAsync();
                return item.Id;
            }
        }

        /// <summary>
        /// 添加推送消息的格式
        /// </summary>
        /// <param name="_dbContext"></param>
        /// <param name="code"></param>
        /// <param name="desc"></param>
        /// <param name="rate"></param>
        /// <returns></returns>
        private async Task<int> _addnoticemessage(IPasteTimerDbContext _dbContext, string code, string desc, int rate)
        {
            var find = await _dbContext.MessageInfo.Where(x => x.Code == code).AsNoTracking().FirstOrDefaultAsync();
            if (find != null && find != default)
            {
                return find.Id;
            }
            else
            {
                var item = new MessageInfo();
                item.Code = code;
                item.Desc = desc;
                item.SendRate = rate;
                _dbContext.Add(item);
                await _dbContext.SaveChangesAsync();
                return item.Id;
            }
        }

        /// <summary>
        /// 添加系统任务
        /// </summary>
        /// <returns></returns>
        private async Task<bool> AddSystemHandler(IPasteTimerDbContext _dbContext)
        {

            var find = await _dbContext.TaskInfo.Where(x => x.Groups == "slave" && x.Assembly == "CollectHandler").AsNoTracking().FirstOrDefaultAsync();
            if (find == null || find == default)
            {
                var one = new TaskInfo();
                one.Assembly = "CollectHandler";
                one.Name = "回收服务";
                one.AssemblyZip = "";
                one.EndDate = DateTime.Now.AddYears(100);
                one.FileVersion = 1000;
                one.Groups = "slave";
                one.StartDate = DateTime.Now;
                one.RetryCount = 1;
                one.RunWay = RunWay.Assembly;
                one.IsEnable = true;
                one.TaskType = TaskType.OnTime;
                one.TickRegex = "(.*)03:00:00";
                one.HttpBody = "";
                one.HttpPath = "";
                _dbContext.Add(one);
                await _dbContext.SaveChangesAsync();
            }

            var report = await _dbContext.TaskInfo.Where(x => x.Groups == "slave" && x.Assembly == "ReportHandler").AsNoTracking().FirstOrDefaultAsync();
            if (report == null || report == default)
            {
                var one = new TaskInfo();
                one.Assembly = "ReportHandler";
                one.Name = "报告服务";
                one.AssemblyZip = "";
                one.EndDate = DateTime.Now.AddYears(100);
                one.FileVersion = 1000;
                one.Groups = "slave";
                one.StartDate = DateTime.Now;
                one.RetryCount = 1;
                one.RunWay = RunWay.Assembly;
                one.IsEnable = true;
                one.TaskType = TaskType.OnTime;
                one.TickRegex = "(.*):00:01";
                one.HttpBody = "";
                one.HttpPath = "";
                _dbContext.Add(one);
                await _dbContext.SaveChangesAsync();
            }

            var test = await _dbContext.TaskInfo.Where(x => x.Groups == "slave" && x.Assembly == "RemoteTestHandler").AsNoTracking().FirstOrDefaultAsync();
            if (test == null || test == default)
            {
                var one = new TaskInfo();
                one.Assembly = "RemoteTestHandler";
                one.Name = "测试服务";
                one.AssemblyZip = "";
                one.EndDate = DateTime.Now.AddDays(3);
                one.FileVersion = 1000;
                one.Groups = "slave";
                one.StartDate = DateTime.Now;
                one.RetryCount = 1;
                one.RunWay = RunWay.Assembly;
                one.IsEnable = true;
                one.TaskType = TaskType.Tick;
                one.TickRegex = "00:01:00";
                one.HttpBody = "";
                one.HttpPath = "";
                _dbContext.Add(one);
                await _dbContext.SaveChangesAsync();
            }
            return true;
        }

        #endregion

    }
}
